#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Date    : 2020-02-06 20:06:47
# @Author  : 胡宗尧 (1448424184@qq.com)
# @Link    : https://www.cnblogs.com
# @Version : $Id$
import pygame
import random
from pygame.locals import *
from sys import exit

pygame.init()
SCREEN_SIZE = (600, 600)  # 3*3*3*2*2*2*2*5
screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32)
font = pygame.font.SysFont('arial', 15)
clock = pygame.time.Clock()
car_group = pygame.sprite.Group()
up_cars = pygame.sprite.Group()
down_cars = pygame.sprite.Group()
right_cars = pygame.sprite.Group()
left_cars = pygame.sprite.Group()
BLACK = (0, 0, 0)
number_of_cars = 10
# class Vector2(tuple):
#     def __new__(typ, x=1.0, y=1.0):
#         n = tuple.__new__(typ, (int(x), int(y)))
#         n.x = x
#         n.y = y
#         return n
#     def __mul__(self, other):
#         return self.__new__(type(self), self.x*other, self.y*other)
#     def __add__(self, other):
#         return self.__new__(type(self), self.x+other.x, self.y+other.y)
#     def __str__(self):
#         return "(%s, %s)"%(self.x, self.y)
#     @staticmethod
#     def from_points(P1, P2):
#         return Vector2( P2[0] - P1[0], P2[1] - P1[1] )
#     def get_magnitude(self):
#         return math.sqrt( self.x**2 + self.y**2 )
#     def normalize(self):
#         magnitude = self.get_magnitude()
#         self.x /= magnitude
#         self.y /= magnitude


class Car(pygame.sprite.Sprite):
    """docstring for Car"""

    def __init__(self, direction, position, speed):
        pygame.sprite.Sprite.__init__(self)
        self.direction = direction
        self.color = (random.randint(0, 255), random.randint(
            0, 255), random.randint(0, 255))
        self.speed = speed
        self.position = position
        if self.direction == "Up":
            self.rect = pygame.Rect(350, self.position, 15, 30)
            up_cars.add(self)
        elif self.direction == "Down":
            self.rect = pygame.Rect(250, self.position, 15, 30)
            down_cars.add(self)
        elif self.direction == "Right":
            self.rect = pygame.Rect(self.position, 350, 30, 15)
            right_cars.add(self)
        elif self.direction == "Left":
            self.rect = pygame.Rect(self.position, 250, 30, 15)
            left_cars.add(self)
        pygame.sprite.spritecollide(self, car_group, True)

    def change_X(self, a):
        self.rect.x += a

    def change_Y(self, a):
        self.rect.y += a

    def get_X(self):
        return self.rect.x

    def get_Y(self):
        return self.rect.y

    def move(self):
        distance = []
        car_X = []
        car_Y = []
        if self.direction == "Right":
            self.change_X(self.speed)
            for car in right_cars:
                d = car.get_X() - self.get_X() - 30
                car_X.append(car.get_X())
                if d > 0:
                    distance.append(d)
            if distance != [] and min(distance) <= 30:
                self.speed -= (self.speed / min(distance)) * 2
                self.speed = abs(self.speed)
            else:
                self.speed += 0.1
            if self.get_X() >= 600:
                car_group.remove(self)
                right_cars.remove(self)
            elif min(car_X) > 0 and len(right_cars) <= number_of_cars:
                car_group.add(Car("Right", -30, 0.2))

        elif self.direction == "Left":
            self.change_X(-self.speed)
            for car in left_cars:
                d = self.get_X() - car.get_X() - 30
                car_X.append(car.get_X())
                if d > 0:
                    distance.append(d)
            if distance != [] and min(distance) <= 30:
                self.speed -= (self.speed / min(distance)) * 2
                self.speed = abs(self.speed)
            else:
                self.speed += 0.1
            if self.get_X() <= -30:
                car_group.remove(self)
                left_cars.remove(self)
            elif max(car_X) < 570 and len(left_cars) <= number_of_cars:
                car_group.add(Car("Left", 600, 0.2))

        elif self.direction == "Up":
            self.change_Y(-self.speed)
            if self.get_Y() <= 0:
                self.rect.y = 600
        elif self.direction == "Down":
            self.change_Y(self.speed)
            if self.get_Y() >= 600:
                self.rect.y = 0

    def draw(self):
        pygame.draw.rect(screen, self.color, self.rect)


def draw_background():
    pygame.draw.lines(screen, (255, 255, 255), False, [
                      (200, 0), (200, 200), (0, 200)], 2)
    pygame.draw.lines(screen, (255, 255, 255), False, [
                      (400, 0), (400, 200), (600, 200)], 2)
    pygame.draw.lines(screen, (255, 255, 255), False, [
                      (0, 400), (200, 400), (200, 600)], 2)
    pygame.draw.lines(screen, (255, 255, 255), False, [
                      (600, 400), (400, 400), (400, 600)], 2)


# for i in range(16):
#     car_group.add(Car(["Right", "Left", "Up", "Down"][i % 4],random.randint(0, 600)))

for _ in range(number_of_cars):
    car_group.add(Car("Right", random.randint(0, 600), random.randint(1, 10)))

for _ in range(number_of_cars):
    car_group.add(Car("Left", random.randint(0, 600), random.randint(1, 10)))

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            exit()
        elif event.type == KEYDOWN and event.key == K_SPACE:
            exit()

    for car in car_group:
        car.move()
        car.draw()

    draw_background()

    pygame.display.update()
    pygame.Surface.fill(screen, (0, 0, 0))
    clock.tick(30)

